package com.motong.gongdan.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.motong.gongdan.entity.*;
import com.motong.gongdan.mapper.FormTableMapper;
import com.motong.gongdan.util.LoginUtil;
import com.motong.gongdan.util.TimeUtil;
import com.motong.gongdan.vo.system.Erp.vo.PushOrderNumVo;
import com.motong.gongdan.vo.system.otherVo.EditSalesOrderProductVo;
import com.motong.gongdan.vo.system.otherVo.ProcessRoteProcessVo;
import com.motong.gongdan.vo.system.otherVo.RelatedSalesInfoVo;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author lsw
 * @time 2022/5/23 16:31
 */
@Service
public class FormTableService extends ServiceImpl<FormTableMapper, FormTable> {


    @Resource
    ProductService productService;
    @Resource
    ProcessRouteService processRouteService;
    @Resource
    WorkOrderService workOrderService;
    @Resource
    ProcessesService processesService;
    @Resource
    MissionService missionService;
    @Resource
    FormTableDetailService formTableDetailService;
    @Resource
    WorkReportService workReportService;
    @Resource
    MongoTemplate mongoTemplate;
    @Resource
    CustomFieldService customFieldService;
    @Resource
    private CustomNumberService customNumberService;
    @Resource
    private CustomEventService customEventService;


    /**
     * 新建
     */
    public void createForm(List<FormTableDetail> formTableDetails, FormTable formTable) throws ParseException {
        for (FormTableDetail f : formTableDetails) {
            Product product = productService.getById(f.getProductId());
//                ft.setProductIds(ft.getProductIds() == null ? product.getId() + "" : ft.getProductIds() + "," + product.getId());
            //创建工单
            WorkOrder wo = new WorkOrder();
            //设置工单编号
            Random random = new Random();
            int number = random.nextInt(9000) + 1000;
            wo.setCode(formTable.getCode() + "-" + number);
            //设置产品id
            wo.setProductId(product.getId());
            //设置创建人
            wo.setCreateId(LoginUtil.getLoginUserId());
            //设置计划开始 结束时间
            SimpleDateFormat sdf = new SimpleDateFormat(TimeUtil.DEFAULT_DATE_FORMAT);
            Date startTime = sdf.parse(TimeUtil.getDayEarlyTime());
            Date endTime = sdf.parse(TimeUtil.getDayLateTime());
            wo.setStartTime(startTime);
            wo.setEndTime(endTime);
            wo.setPlanedNumber(f.getHandleNumber());
            if (product.getProcessRouteId() != null) {
                ProcessRoute processRoute = processRouteService.getById(product.getProcessRouteId());
                List<ProcessRoteProcessVo> processesRoteProcessVoList = JSONArray.parseArray(processRoute.getProcessList(), ProcessRoteProcessVo.class);
                for (ProcessRoteProcessVo roteProcessVo : processesRoteProcessVoList) {
                    wo.setProcessId(wo.getProcessId() == null ? roteProcessVo.getId() + "" : wo.getProcessId() + "," + roteProcessVo.getId());
                }
            }
            if (!CollectionUtils.isEmpty(f.getCustomFieldVos())) {
                wo.setOther(customFieldService.handleObjectCreateOrEdit(f.getCustomFieldVos()).toJSONString());
            }
            workOrderService.save(wo);
            if (!CollectionUtils.isEmpty(f.getCustomFieldVos())) {
                WorkOrder workOrder = new WorkOrder();
                workOrder.setCode(wo.getCode());
                workOrder.setCustomFieldMess(JSONArray.parseArray(wo.getOther()));
                workOrder.setId(wo.getId());
                mongoTemplate.save(workOrder);
            }
//                ft.setWorkOrderCode(ft.getWorkOrderCode() == null ? wo.getCode() : ft.getWorkOrderCode() + "," + wo.getCode());
            //创建任务
            List<String> process = Arrays.asList(wo.getProcessId().split(","));
            for (String s : process) {
                Processes pro = processesService.getById(Integer.valueOf(s));
                Mission mission = new Mission();
                mission.setWorkOrderCode(wo.getCode());
                mission.setProductCode(product.getCode());
                mission.setProcessCode(pro.getCode());
                mission.setPlanedNumber(f.getHandleNumber());
                mission.setGoodProductNumber(BigDecimal.valueOf(0));
                mission.setBadProductNumber(BigDecimal.valueOf(0));
                mission.setProcessState(0);
                mission.setStartTime(wo.getStartTime());
                mission.setEndTime(wo.getEndTime());
                if (process.size() - 1 == process.indexOf(s)) {
                    mission.setLast(0);
                } else {
                    mission.setLast(process.indexOf(s) + 1);
                }
                BigDecimal rate = mission.getPlanedNumber().divide(f.getHandleNumber(), 6, BigDecimal.ROUND_DOWN);
                mission.setRate(rate);
                missionService.save(mission);
            }

            f.setFtCode(formTable.getCode());
            f.setWorkOrderCode(wo.getCode());
            formTableDetailService.save(f);
        }


    }

    /**
     * 删除
     */
    public void dleForm(List<FormTableDetail> formTableDetails) {
        this.delProduct(formTableDetails.stream().map(FormTableDetail::getId).collect(Collectors.toList()));
//        for (FormTableDetail ftd : formTableDetails) {
//            //从下往上删除
//            List<Mission> missions = missionService.list(new QueryWrapper<Mission>().eq("work_order_code", ftd.getWorkOrderCode()));
//            missions.forEach(m -> {
//                workReportService.remove(new QueryWrapper<WorkReport>().eq("mission_id", m.getId()));
//            });
//            missionService.remove(new QueryWrapper<Mission>().eq("work_order_code", ftd.getWorkOrderCode()));
//            workOrderService.remove(new QueryWrapper<WorkOrder>().eq("code", ftd.getWorkOrderCode()));
//            formTableDetailService.removeById(ftd.getId());
//        }
    }

    /**
     * 添加销售订单内商品详情
     *
     * @param editSalesOrderProductVo 销售订单内部商品信息
     * @param formTableCode           销售订单编码
     * @param workerOrderIndex        当前详情数量+1(即生成工单的下标)
     */
    public void saveProduct(List<EditSalesOrderProductVo> editSalesOrderProductVo, String formTableCode, Integer workerOrderIndex) {
        if (Objects.isNull(editSalesOrderProductVo) || editSalesOrderProductVo.isEmpty()) {
            return;
        }
        // 根据产品id获取绑定的工艺路线
        Set<Integer> productIds = editSalesOrderProductVo.stream().map(EditSalesOrderProductVo::getProductId).collect(Collectors.toSet());
        // 需要用到的商品信息
        List<Map<String, Object>> productData = productService.getProcessByProductId(productIds);
        Integer loginUserId = LoginUtil.getLoginUserId();
        Map<Integer, Map<String, Object>> productIdDataMap = new HashMap<>();
        productData.forEach(i -> productIdDataMap.put(Integer.valueOf(i.get("productId").toString()), i));
        List<WorkOrder> workOrders = new ArrayList<>();
        List<Mission> missions = new ArrayList<>();
        List<FormTableDetail> formTableDetails = new ArrayList<>();
        AtomicReference<Integer> num = new AtomicReference<>(workerOrderIndex);
        editSalesOrderProductVo.forEach(i -> {
            Map<String, Object> product = productIdDataMap.get(i.getProductId());
            cn.hutool.json.JSONArray processList = JSONUtil.parseArray(Optional.ofNullable(product.get("processList")).orElse("[]"));
            String processIds = processList.stream().map(d -> JSONUtil.parseObj(d).get("id").toString()).collect(Collectors.joining(","));
            // 整合工单数据
            DateTime date = DateUtil.date();
            WorkOrder workOrder = new WorkOrder().setStartTime(Optional.ofNullable(i.getStartTime()).orElse(DateUtil.beginOfDay(date)))
                    .setEndTime(Optional.ofNullable(i.getEndTime()).orElse(DateUtil.endOfDay(date))).setPlanedNumber(i.getHandleNumber())
                    .setActualNumber(i.getFinishNumber()).setOther(JSONUtil.toJsonStr(i.getCustomFieldVos())).setId(i.getWorkOrderId()).setState(0)
                    .setProductId(Convert.toInt(product.get("productId"))).setCreateId(loginUserId).setEditId(loginUserId).setProcessId(processIds).setIsUrgent(0);
            if (Objects.isNull(i.getWorkOrderId())) {
                workOrder.setCode(formTableCode + "-" + num);
                num.getAndSet(num.get() + 1);
            }
            FormTableDetail formTableDetail = new FormTableDetail().setFtCode(formTableCode).setProductId(Convert.toInt(i.getProductId())).setWorkOrderCode(workOrder.getCode())
                    .setHandleNumber(workOrder.getPlanedNumber());
            formTableDetails.add(formTableDetail);
            //返回详情id(erp需要)
            i.setRealData(formTableDetail);
            // 整合任务数据
            // 最后一道工序order为0!!!!!
            AtomicInteger order = new AtomicInteger(1);
            processList.forEach(
                    d -> {
                        cn.hutool.json.JSONObject process = JSONUtil.parseObj(d);
                        Mission mission = new Mission().setWorkOrderCode(workOrder.getCode()).setProcessCode(process.get("code").toString())
                                .setPlanedNumber(Convert.toBigDecimal(process.get("rate")).multiply(i.getHandleNumber()))
                                .setRate(Convert.toBigDecimal(process.get("rate"))).setLast(order.get() == processList.size() ? 0 : order.getAndIncrement())
                                .setStartTime(i.getStartTime()).setEndTime(i.getEndTime()).setProcessState(0).setProductCode(product.get("productCode").toString()).setIsUrgent(0);
                        missions.add(mission);
                    }
            );
            workOrders.add(workOrder);
            customEventService.sendCustomEventMsg(0, 0, 0, workOrder, null, null);
        });
        workOrderService.saveBatch(workOrders);
        missionService.saveBatch(missions);
        formTableDetailService.saveBatch(formTableDetails);

    }


    /**
     * 编辑销售订单内商品详情
     *
     * @param editSalesOrderProductVo 销售订单内部商品信息
     */
    public void updateProduct(List<EditSalesOrderProductVo> editSalesOrderProductVo) {
        if (Objects.isNull(editSalesOrderProductVo) || editSalesOrderProductVo.isEmpty()) {
            return;
        }
        // 获取工单编码
        Set<String> wOCodes = editSalesOrderProductVo.stream().map(EditSalesOrderProductVo::getWorkOrderCode).collect(Collectors.toSet());
        // 获取所有工单信息
        Map<String, WorkOrder> codeOrderData = new HashMap<>();
        workOrderService.list(new LambdaQueryWrapper<WorkOrder>().in(WorkOrder::getCode, wOCodes)).forEach(i -> codeOrderData.put(i.getCode(), i));
        // 筛选需要操作的工单,任务
        List<WorkOrder> workOrders = new ArrayList<>();
        List<Mission> missions;
        Map<String, WorkOrder> codeDataMap = new HashMap<>();
        List<FormTableDetail> formTableDetails = new ArrayList<>();

        Set<Integer> productIds = editSalesOrderProductVo.stream().map(EditSalesOrderProductVo::getProductId).collect(Collectors.toSet());
        Map<Integer, String> productIdCodeMap = new HashMap<>(productIds.size());
        List<Product> products = productService.listByIds(productIds);
        products.forEach(i -> productIdCodeMap.put(i.getId(), i.getCode()));

        if (codeOrderData.isEmpty()) {
            return;
        }
        editSalesOrderProductVo.forEach(i -> {
                    WorkOrder workOrder = codeOrderData.get(i.getWorkOrderCode());
                    String customFieldStr = JSONUtil.toJsonStr(i.getCustomFieldVos());
                    if (Objects.nonNull(workOrder) && !workOrder.getPlanedNumber().equals(i.getHandleNumber()) || !workOrder.getProductId().equals(i.getProductId()) || workOrder.getStartTime() != i.getStartTime() || workOrder.getEndTime() != i.getEndTime() || !workOrder.getOther().equals(customFieldStr)) {
                        workOrder.setStartTime(i.getStartTime()).setEndTime(i.getEndTime()).setOther(customFieldStr);
                        codeDataMap.put(workOrder.getCode(), workOrder);
                        if ((!workOrder.getPlanedNumber().equals(i.getHandleNumber())) || (!workOrder.getProductId().equals(i.getProductId()))) {
                            workOrder.setPlanedNumber(i.getHandleNumber()).setProductId(i.getProductId()).setProductCode(productIdCodeMap.get(i.getProductId()));
                            formTableDetails.add(new FormTableDetail().setId(i.getId()).setHandleNumber(i.getHandleNumber()).setProductId(i.getProductId()));
                        }
                        workOrders.add(workOrder);
                    }
                }
        );
        // 获取需要更新的任务信息
        missions = missionService.list(new LambdaQueryWrapper<Mission>().in(Mission::getWorkOrderCode, workOrders.stream().map(WorkOrder::getCode).collect(Collectors.toSet())));
        missions.forEach(i -> i.setStartTime(codeDataMap.get(i.getWorkOrderCode()).getStartTime()).setPlanedNumber(i.getRate().multiply(codeDataMap.get(i.getWorkOrderCode()).getPlanedNumber())).setEndTime(codeDataMap.get(i.getWorkOrderCode()).getEndTime())
                .setProductCode(codeDataMap.get(i.getWorkOrderCode()).getProductCode()));

        if (!workOrders.isEmpty()) {
            workOrderService.updateBatchById(workOrders);
            formTableDetailService.updateBatchById(formTableDetails);
        }
        if (!missions.isEmpty()) {
            missionService.updateBatchById(missions);
        }
    }


    /**
     * 删除销售单商品相关信息
     *
     * @param formTableDetailsIds x
     */
    public void delProduct(List<Integer> formTableDetailsIds) {
        if (!CollectionUtils.isEmpty(formTableDetailsIds)) {
            List<FormTableDetail> formTableDetails = formTableDetailService.listByIds(formTableDetailsIds);
            // 工单编码
            Set<String> wOCodes = formTableDetails.stream().map(FormTableDetail::getWorkOrderCode).collect(Collectors.toSet());
            workOrderService.removeByCodeList(wOCodes);
            // 删除详情
            formTableDetailService.removeByIds(formTableDetailsIds);
        }
    }

    /**
     * 根据工单编码获取销售相关信息
     *
     * @param workOrderCodes 工单编码集合
     * @return 销售单统计相关信息
     */
    public List<RelatedSalesInfoVo> getSalesInfoByWorkOrderCodes(Set<String> workOrderCodes) {
        return this.baseMapper.getSalesInfoByWorkOrderCodes(workOrderCodes);
    }

    /**
     * 获取远程erp相关销售信息
     *
     * @param code 工单编码
     * @return 程erp相关销售信息
     */
    public PushOrderNumVo getErpSalesInfo(String code) {
       return this.baseMapper.getErpSalesInfo(code);
    }
}
